package com.actor;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * @author sad
 */
public class ActorSystem {
    private final ScheduledExecutorService scheduler;
    private final QueueThreadPool threadPool;
    private final NullActor nullActor;
    private final Map<String, Actor> actors = Collections.synchronizedMap(new HashMap<String, Actor>());

    public ActorSystem() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        threadPool = new QueueThreadPool();
        nullActor = new NullActor(this);
    }

    public ScheduledExecutorService getScheduler() {
        return scheduler;
    }

    void registerActor(Actor actor) {
        if (actors.containsKey(actor.getActorName())) {
            throw new IllegalArgumentException("You already has actor with name [" + actor.getActorName() + "]");
        }

        getThreadPool().addToPool(actor);
        actors.put(actor.getActorName(), actor);
    }

    void unregisterActor(Actor actor) {
        unregisterActorNotRemove(actor);
        actors.remove(actor.getActorName());
    }

    void unregisterActorNotRemove(Actor actor) {
        getThreadPool().removeFormPool(actor);
    }

    public NullActor getNullActor() {
        return nullActor;
    }

    public ActorRef getActorByName(String name) {
        return actors.get(name);
    }

    public QueueThreadPool getThreadPool() {
        return threadPool;
    }

    public void stop() {
        for (Actor actor : actors.values()) {
            unregisterActorNotRemove(actor);
        }

        actors.clear();
        getThreadPool().stop();
    }
}
